package com.example.kotlin

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewmodel.compose.viewModel

/**
 * 界面状态描述屏幕上显示的内容，而应用逻辑则描述应用的行为方式以及应如何响应状态变化。
 * 逻辑分为两种类型：第一种是界面行为或界面逻辑，第二种是业务逻辑。
 *
 * 界面逻辑涉及如何在屏幕上显示状态变化（例如导航逻辑或显示信息提示控件）。
 * 业务逻辑决定如何处理状态更改（例如付款或存储用户偏好设置）。该逻辑通常位于业务层或数据层，但绝不会位于界面层。
 * ViewModel 提供界面状态以及对位于应用其他层中的业务逻辑的访问。
 * 此外，ViewModel 还会在配置更改后继续保留，因此其生命周期比组合更长。
 * ViewModel 可以遵循 Compose 内容（即 activity 或 fragment）的主机的生命周期，也可以遵循导航图的目的地的生命周期（如果您使用的是 Compose Navigation 库）。
 *
 * */

/**
 * 警告：ViewModel 并不是组合的一部分。因此，您不应保留可组合项中创建的状态（例如，记住的值），因为这可能会导致内存泄漏。
 *
 * 建议将 ViewModel 用于屏幕级可组合项，即靠近从导航图的 activity、fragment 或目的地调用的根可组合项。
 * 绝不应将 ViewModel 传递给其他可组合项，而是应当仅向它们传递所需的数据以及以参数形式执行所需逻辑的函数。
 * 如需了解详情，请参阅 ViewModel 和状态容器部分(https://developer.android.google.cn/jetpack/compose/state?hl=zh-cn#state-in-composables)
 * 以及我们的 Compose 和其他库的相关文档(https://developer.android.google.cn/jetpack/compose/libraries?hl=zh-cn#viewmodel)。
 * */

private class WellnessViewModel : ViewModel() {
    private val _taskList = listOf<WellnessTask>().toMutableStateList()
    val taskList: List<WellnessTask>
        get() = _taskList

    fun remove(item: WellnessTask) {
        _taskList.remove(item)
    }

    //最后一个重构是将选中状态和逻辑迁移到 ViewModel。这样一来，代码将变得更简单且更易于测试，并且所有状态均由 ViewModel 管理。
    fun changeTaskChecked(item: WellnessTask, checked: Boolean) =
        taskList.find { it.id == item.id }?.let { task ->
            task.checked.value = checked
        }
}

@Composable
private fun WellnessTasksList(
    list: List<WellnessTask>,
    onCheckedTask: (WellnessTask, Boolean) -> Unit,
    onCloseTask: (WellnessTask) -> Unit,
    modifier: Modifier = Modifier
) {
    LazyColumn(
        modifier = modifier
    ) {
        items(
            items = list,
            key = { task -> task.id }
        ) { task ->
            WellnessTaskItem(
                taskName = task.label,
                checked = task.checked.value,
                onCheckedChange = { checked -> onCheckedTask(task, checked) },
                onClose = { onCloseTask(task) }
            )
        }
    }
}

@Composable
private fun WellnessScreen(
    modifier: Modifier = Modifier,
    wellnessViewModel: WellnessViewModel = viewModel()
) {
    Column(modifier = modifier) {
        WellnessTasksList(
            list = wellnessViewModel.taskList,
            onCheckedTask = { wellnessTask, b ->
                wellnessViewModel.changeTaskChecked(
                    wellnessTask,
                    b
                )
            },
            onCloseTask = { task -> wellnessViewModel.remove(task) })
    }
}